﻿// ===============================================================================
// XCI.NET 西安交通信息WinForm开发框架 2018 版权所有
// ===============================================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Windows.Forms;
using DevExpress.Utils;
using DevExpress.XtraBars;
using XCI.Core;
using XCI.Data.Entity;
using XCI.Helper;
using XCI.Windows.Helper;
using XCI.Windows.Controls;
using DevExpress.XtraEditors;
using DevExpress.XtraLayout;
using DevExpress.XtraSplashScreen;

namespace XCI.Windows.Forms
{
    /// <summary>
    /// 
    /// </summary>
    public partial class FrmBase : DevExpress.XtraEditors.XtraForm
    {
        private Dictionary<string, object> _firstActions = new Dictionary<string, object>();
        private Dictionary<string, string> _paramData;

        /// <summary>
        /// 
        /// </summary>
        public FrmBase()
        {
            InitializeComponent();
            this.Icon = XCI.Windows.Properties.Resources.Transport;
        }

        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        public string ParamDataString { get; set; }


        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        [Browsable(false)]
        public Dictionary<string, string> ParamData
        {
            get
            {
                if (DesignMode)
                {
                    return new Dictionary<string, string>();
                }
                if (_paramData == null)
                {
                    _paramData = WinHelper.ParseUrlParamDic(ParamDataString);
                }
                return _paramData;
            }
        }

        /// <summary>
        /// 是否预加载
        /// </summary>
        public bool PreLoading { get; set; }

        /// <summary>
        /// 是否正在初始化
        /// </summary>
        protected bool IsInit { get; private set; }

        /// <summary>
        /// 是否正在绑定数据
        /// </summary>
        protected bool IsBinding { get; private set; }
        protected bool IsBinding1 { get; private set; }
        protected bool IsBinding2 { get; private set; }
        protected bool IsBinding3 { get; private set; }
        protected bool IsBinding4 { get; private set; }
        ///// <summary>
        ///// 头部控件
        ///// </summary>
        //protected virtual CaptionControl FormCaptionControl { get { return null; } }

        /// <summary>
        /// 初始化控件
        /// </summary>
        /// <param name="action">初始化函数</param>
        protected void BeginInit(Action action)
        {
            try
            {
                IsInit = true;
                action?.Invoke();
            }
            finally
            {
                IsInit = false;
            }
        }

        /// <summary>
        /// 控件初始化完成
        /// </summary>
        /// <param name="action">调用函数</param>
        protected void EndInit(Action action)
        {
            if (IsInit == false)
            {
                action?.Invoke();
            }
        }

        /// <summary>
        /// 包装数据绑定
        /// </summary>
        protected void DataBinding(Action action)
        {
            if (IsBinding) return;

            try
            {
                IsBinding = true;
                action?.Invoke();
            }
            finally
            {
                IsBinding = false;
            }
        }

        protected void DataBinding1(Action action)
        {
            if (IsBinding1) return;

            try
            {
                IsBinding1 = true;
                action?.Invoke();
            }
            finally
            {
                IsBinding1 = false;
            }
        }

        protected void DataBinding2(Action action)
        {
            if (IsBinding2) return;

            try
            {
                IsBinding2 = true;
                action?.Invoke();
            }
            finally
            {
                IsBinding2 = false;
            }
        }

        protected void DataBinding3(Action action)
        {
            if (IsBinding3) return;

            try
            {
                IsBinding3 = true;
                action?.Invoke();
            }
            finally
            {
                IsBinding3 = false;
            }
        }

        protected void DataBinding4(Action action)
        {
            if (IsBinding4) return;

            try
            {
                IsBinding4 = true;
                action?.Invoke();
            }
            finally
            {
                IsBinding4 = false;
            }
        }

        /// <summary>
        /// 每个页面只执行一次
        /// </summary>
        /// <param name="name">操作名称</param>
        /// <param name="action">回调函数</param>
        protected void OnceAction(string name, Action action)
        {
            if (!_firstActions.ContainsKey(name))
            {
                _firstActions[name] = 1;
                action?.Invoke();
            }
        }

        protected void ControlInvoke(Control control, Action action)
        {
            control.Invoke(new Action(action));
        }

        ///// <summary>
        ///// 隐藏头部控件
        ///// </summary>
        //public void HideHeadControl()
        //{
        //    if (FormCaptionControl != null)
        //    {
        //        FormCaptionControl.Visible = false;
        //    }
        //}

        ///// <summary>
        ///// 设置头部控件标题
        ///// </summary>
        ///// <param name="caption">标题</param>
        //public void SetCaption(string caption)
        //{
        //    if (FormCaptionControl != null)
        //    {
        //        FormCaptionControl.CaptionText = caption;
        //    }
        //}

        /// <summary>
        /// 显示操作结果
        /// </summary>
        /// <param name="result">操作结果</param>
        protected void ShowResultMessage(BoolMessage result)
        {
            if (!string.IsNullOrEmpty(result.Msg))
            {
                if (result.Success)
                {
                    MessageBoxHelper.ShowMessage(result.Msg);
                }
                else
                {
                    MessageBoxHelper.ShowError(result.Msg);
                }
            }
        }

        protected override void OnLoad(EventArgs e)
        {
            if (DesignMode)
            {
                DevExpress.Utils.AppearanceObject.DefaultFont = new Font("微软雅黑", 9.75F);

                RepositoryItemComboBoxEditx.RegisterComboBoxEditx();
                RepositoryItemRadioGroupx.RegisterRadioGroupx();
                RepositoryItemImageComboBoxEditx.RegisterImageComboBoxEditx();
                RepositoryItemComboGridEditx.RegisterComboGridEditx();
            }
            //else
            //{
            //    SplashHelper.CloseWait();
            //}

            if (!PreLoading)
            {
                base.OnLoad(e);
            }
        }

        /// <summary>
        /// 开始计算程序执行时间(默认返回:查询耗时：xx毫秒)
        /// </summary>
        /// <param name="action">执行内容</param>
        /// <returns>返回程序执行的时间</returns>
        protected TimeSpan ElapsedTime(Action action)
        {
            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();
            action();
            stopwatch.Stop();
            return stopwatch.Elapsed;
        }

        /// <summary>
        /// 开始计算程序执行时间(默认返回:查询耗时：xx毫秒)
        /// </summary>
        /// <param name="barItem">文本框项</param>
        /// <param name="action">执行内容</param>
        /// <returns>返回程序执行的时间</returns>
        protected void ElapsedTime(BarStaticItem barItem, Action action)
        {
            TimeSpan ts = ElapsedTime(action);
            ElapsedTime(barItem, ts);
        }

        /// <summary>
        /// 开始计算程序执行时间(默认返回:查询耗时：xx毫秒)
        /// </summary>
        /// <param name="barItem">文本框项</param>
        /// <param name="elaspTime">执行耗时</param>
        /// <returns>返回程序执行的时间</returns>
        protected void ElapsedTime(BarStaticItem barItem, TimeSpan elaspTime)
        {
            barItem.Caption = $"耗时:{elaspTime.TotalMilliseconds:###0.##} ms";
        }

        /// <summary>
        /// 设置窗口的DialogResult的值为OK
        /// </summary>
        protected void ResultOk()
        {
            this.DialogResult = System.Windows.Forms.DialogResult.OK;
        }

        /// <summary>
        /// 设置窗口的DialogResult的值为Cancel
        /// </summary>
        protected void ResultCancel()
        {
            this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
        }

        protected void EditFormEscResultCancel(string comfirmMessage = "确定要关闭当前窗口吗?")
        {
            if (MessageBoxHelper.ShowWarnYesNo(comfirmMessage) != DialogResult.Yes)
            {
                return;
            }
            this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
        }

        protected void DetailsFormEscResultCancel()
        {
            this.DialogResult = System.Windows.Forms.DialogResult.Cancel;
        }

        protected void EnterPressHandle(KeyPressEventArgs e, Action action)
        {
            if (e.KeyChar == 13) //回车
            {
                action?.Invoke();
                e.Handled = true;
            }
        }

        /// <summary>
        /// 验证数据对象
        /// </summary>
        /// <param name="model">数据对象</param>
        /// <param name="raisError">是否抛出错误信息</param>
        /// <returns>验证通过返回true</returns>
        protected virtual bool ValidModel(object model, bool raisError = true)
        {
            var vresult = ValidateHelper.ValidationAs(model);
            if (!vresult.Success && raisError) MessageBoxHelper.ShowError(vresult.Msg);
            return vresult.Success;
        }

        /// <summary>
        /// 验证过滤对象
        /// </summary>
        /// <param name="filter">过滤对象</param>
        /// <param name="raisError">是否抛出错误信息</param>
        /// <returns>验证通过返回true</returns>
        protected bool ValidFilter(object filter, bool raisError = true)
        {
            var vresult = ValidateHelper.ValidationAs(filter);
            if (!vresult.Success && raisError) MessageBoxHelper.ShowError(vresult.Msg);
            return vresult.Success;
        }

        /// <summary>
        /// 导出Excel
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="data">导出的数据</param>
        /// <param name="defaultFileName">默认文件名</param>
        protected void ExcelExport<T>(IEnumerable<T> data, string defaultFileName = null) where T : class, new()
        {
            var meta = EntityHelper.Get<T>();
            var fname = defaultFileName;
            if (string.IsNullOrEmpty(fname))
            {
                fname = meta.TableAttr.Caption ?? meta.TableAttr.Name;
            }
            ExcelExportCore(() => ExcelHelper.Export(data), fname);
        }

        /// <summary>
        /// 导出Excel
        /// </summary>
        /// <typeparam name="T">对象类型</typeparam>
        /// <param name="data">导出的数据</param>
        /// <param name="sheetName">Sheet名称</param>
        /// <param name="heads">表头列表</param>
        /// <param name="defaultFileName">默认文件名</param>
        protected void ExcelExport<T>(IEnumerable<T> data, string sheetName,
                                      List<ExcelHead> heads, string defaultFileName = null) where T : class, new()
        {
            WinHelper.ExcelExportCore(this, () => ExcelHelper.Export(data, sheetName, heads), defaultFileName);
        }

        /// <summary>
        /// 显示导出文件对话框
        /// </summary>
        /// <param name="func"></param>
        /// <param name="defaultFileName"></param>
        protected void ExcelExportCore(Func<byte[]> func, string defaultFileName = null)
        {
            WinHelper.ExcelExportCore(this, func, defaultFileName);
        }

        /// <summary>
        /// 注册Esc按键事件
        /// </summary>
        /// <param name="msg"></param>
        /// <param name="keys"></param>
        /// <param name="action"></param>
        protected bool OnEsc(Message msg, Keys keys, Action action)
        {
            int WM_KEYDOWN = 256;
            int WM_SYSKEYDOWN = 260;
            if (msg.Msg == WM_KEYDOWN | msg.Msg == WM_SYSKEYDOWN)
            {
                switch (keys)
                {
                    case Keys.Escape:
                        action?.Invoke();
                        break;
                }

            }
            return false;
        }

        /// <summary>
        /// 获取按钮是否课件枚举
        /// </summary>
        /// <param name="result">结果</param>
        protected BarItemVisibility GetBtnVisibility(bool result)
        {
            if (result)
            {
                return BarItemVisibility.Always;
            }
            return BarItemVisibility.Never;
        }
    }
}